package fr.cephb.bio;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import fr.cephb.json.JSONBuilder;
import fr.cephb.json.JSONable;
import fr.cephb.xml.XML;



public class FastaMapping
	implements JSONable
	{
	private Map<String, File> chromMap=new HashMap<String, File>();
	
	public FastaMapping()
		{
		}
	
	public File get(String name)
		{
		return this.chromMap.get(name);
		}
	
	public Set<String> getNames()
		{
		return new HashSet<String>(this.chromMap.keySet());
		}
	
	public Set<String> getNames(File f)
		{
		Set<String> set=new HashSet<String>();
		for(String s: this.chromMap.keySet())
			{
			if(f.equals(this.chromMap.get(s)))
				{
				set.add(s);
				}
			}
		return set;
		}
	
	
	
	public String getName(File f)
		{
		String name=null;
		for(String s: this.chromMap.keySet())
			{
			if(f.equals(this.chromMap.get(s)))
				{
				if(name==null || s.length()<name.length())
					{
					name=s;
					}
				}
			}
		return name;
		}
	
	public Set<File> getFiles()
		{
		return new HashSet<File>(this.chromMap.values());
		}
	
	public void add(File file)
		{
		String name=file.getName();
		if(name.length()>3 && name.endsWith(".fa"))
			{
			name=name.substring(0, name.length()-3);
			}
		else if(name.length()>6 && name.endsWith(".fasta"))
			{
			name=name.substring(0, name.length()-6);
			}
		put(name, file);
		if(name.length()>3 && name.startsWith("chr"))
			{
			put(name.substring(3), file);
			}
		}
	
	public void put(String name,File file)
		{
		if(chromMap.containsKey(name) &&
			!chromMap.get(name).equals(file))
			{
			throw new IllegalArgumentException("defined twice:"+name);
			}
		this.chromMap.put(name, file);
		}
	
	public void read(File xml) throws IOException
		{
		try
			{
			DocumentBuilderFactory f=DocumentBuilderFactory.newInstance();
			f.setCoalescing(true);
			f.setNamespaceAware(false);
			f.setValidating(false);
			f.setExpandEntityReferences(true);
			f.setIgnoringComments(true);
			f.setIgnoringElementContentWhitespace(true);
			DocumentBuilder docBuilder= f.newDocumentBuilder();
			Document dom=docBuilder.parse(xml);
			Element root=dom.getDocumentElement();
			for(Element c: XML.elements(root,"chromosome"))
				{
				Element path= XML.oneElement(c, "path");
				File sourceFile=new File(path.getTextContent());
				for(Element s: XML.elements(c, "name"))
					{
					String name=s.getTextContent();
					put(name, sourceFile);
					}
				}
			}
		catch(IOException er)
			{
			throw er;
			}
		catch(Exception e)
			{
			throw new IOException(e);
			}
		}
	
	@Override
	public String toJSON()
		{
		return new JSONBuilder().put("mapping", this.chromMap).getString();
		}
	
	@Override
	public String toString()
		{
		return toJSON();
		}
	}
